#include "soc_osal.h"
#include "app_init.h"
#include "cmsis_os2.h"
#include "MQTTClientPersistence.h"
#include "MQTTClient.h"
#include "errcode.h"
#include "uart.h"
#include "pinctrl.h"
#include "osal_debug.h"

#include "lwip/netifapi.h"
#include "wifi_hotspot.h"
#include "wifi_hotspot_config.h"

#include "wifi/wifi_connect.h"
#include "my_device/my_device.h"
#include "oled/oled.h"
#include "my_config.h"
#include "su03t/su03t.h"
#include "json/json.h"
#include "gh_main.h"

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

osThreadId_t main_task_id; // 主任务
osThreadId_t oled_ID; // oled任务


enum state centrl_state = UNKNOW;

char *g_username = "my_central";
char *g_password = "b9cff7584320d8708aaf61b8d7cc634878c527febef78979ce3eb5f12cec9a2b";

// SensorData send_data={0};
// 创建结构体数组存储多个设备数据
#define MAX_DEVICES 4
bool send_flag = false;
static uint8_t uart_total_buffer[200] = {0};  // 静态缓冲区
static uint16_t uart_total_length = 0;
char buff_out[512] = {0};  // 全局缓冲区，大小与静态缓冲区一致
int oled_id=0;


SensorData device_data[MAX_DEVICES] = {0};
bool device_exists[MAX_DEVICES] = {false}; // 标记设备是否存在
int device_count = 0;                      // 当前设备数量
int send_device_index = 0;
int send_to_oled_id = 0;
uint8_t lora_recv[UART_DATA_RECV_SIZE] = {0};
uart_buffer_config_t lora_buffer_config = {.rx_buffer = lora_recv, .rx_buffer_size = UART_DATA_RECV_SIZE};

char g_send_buffer[512] = {0}; // 发布数据缓冲区
char g_response_id[100] = {0}; // 保存命令id缓冲区
char req[] = "reqStatus:1,"; 
char g_response_buf[] =
    "{\"result_code\": 0,\"response_name\": \"control\",\"paras\": {\"result\": \"success\"}}"; // 响应json
uint8_t g_cmdFlag;
MQTTClient client;
volatile MQTTClient_deliveryToken deliveredToken;
extern int MQTTClient_init(void);
// 查找设备索引，如果不存在则尝试添加新设备
int find_device_index(int device_id) 
{
    // 首先查找是否已存在该设备
    for (int i = 0; i < MAX_DEVICES; i++) {
        if (device_exists[i] &&(device_data[i].id == device_id )) {
            return i;
        }
    }
    
    // 如果不存在且未达到最大设备数，添加新设备
    if (device_count < MAX_DEVICES) {
        for (int i = 0; i < MAX_DEVICES; i++) {
            if (!device_exists[i]) {
                // strncpy(device_data[i].id, device_id, MAX_ID_LENGTH - 1);
                device_data[i].id = device_id;
                device_exists[i] = true;
                device_count++;
                osal_printk("New device added: ID=%d, index=%d\r\n", device_id, i);
                return i;
            }
        }
    }
    
    return -1; // 设备数已满
}

// 重置设备数据
void reset_device_data(void) {
    for (int i = 0; i < MAX_DEVICES; i++) {
        if (device_exists[i]) {
            memset(&device_data[i], 0, sizeof(SensorData));
            device_exists[i] = false;
        }
    }
    device_count = 0;
}
// 解析字符串并保存到数组中
void parse_after_equal(const char *input, char *output)
{
    const char *equalsign = strchr(input, '=');
    if (equalsign != NULL) {
        // 计算等于号后面的字符串长度
        strcpy(output, equalsign + 1);
    }
}

// 定义控制状态结构体数组
#define MAX_CONTROL_DEVICES 4
ControlState control_data[MAX_CONTROL_DEVICES] = {0};
bool control_device_exists[MAX_CONTROL_DEVICES] = {false}; // 标记控制设备是否存在
int control_device_count = 0;                             // 当前控制设备数量
// 查找控制设备索引，如果不存在则尝试添加新设备
int find_control_device_index(int device_id) {
    char device_id_str[MAX_FIELD_LEN];
    snprintf(device_id_str, MAX_FIELD_LEN, "%d", device_id);
    
    // 首先查找是否已存在该控制设备
    for (int i = 0; i < MAX_CONTROL_DEVICES; i++) {
        if (control_device_exists[i] && strcmp(control_data[i].id, device_id_str) == 0) {
            return i;
        }
    }
    
    // 如果不存在且未达到最大设备数，添加新控制设备
    if (control_device_count < MAX_CONTROL_DEVICES) {
        for (int i = 0; i < MAX_CONTROL_DEVICES; i++) {
            if (!control_device_exists[i]) {
                snprintf(control_data[i].id, MAX_FIELD_LEN, "%d", device_id);
                control_device_exists[i] = true;
                control_device_count++;
                osal_printk("New control device added: ID=%d, index=%d\r\n", device_id, i);
                return i;
            }
        }
    }
    
    return -1; // 控制设备数已满
}

// 设置设备控制状态
bool set_device_control_state(int device_id, const ControlState *state) {
    char device_id_str[MAX_FIELD_LEN];
    snprintf(device_id_str, MAX_FIELD_LEN, "%d", device_id);
    
    // 确保传入的状态结构体中的ID正确
    ControlState temp_state = *state;
    snprintf(temp_state.id, MAX_FIELD_LEN, "%d", device_id);
    
    int idx = find_control_device_index(device_id);
    if (idx >= 0) {
        control_data[idx] = temp_state;
        osal_printk("Control state updated for device ID=%d\n", device_id);
        return true;
    }
    osal_printk("Failed to set control state: Device ID=%d not found or device limit reached\n", device_id);
    return false;
}


// 获取设备控制状态
bool get_device_control_state(int device_id, ControlState *state) {
    int idx = find_control_device_index(device_id);
    if (idx >= 0 && control_device_exists[idx]) {
        *state = control_data[idx];
        return true;
    }
    return false;
}


/* 回调函数，处理连接丢失 */
void connlost(void *context, char *cause)
{
    unused(context);
    printf("Connection lost: %s\n", cause);
}
int mqtt_subscribe(const char *topic)
{
    printf("subscribe start\r\n");
    MQTTClient_subscribe(client, topic, 1);
    return 0;
}
SensorData* get_Sen(){
    return &device_data[now_id];
}
int mqtt_publish(const char *topic, char *msg)
{
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    int ret = 0;
    pubmsg.payload = msg;
    pubmsg.payloadlen = (int)strlen(msg);
    pubmsg.qos = 1;
    pubmsg.retained = 0;
    printf("[payload]:  %s, [topic]: %s\r\n", msg, topic);
    ret = MQTTClient_publishMessage(client, topic, &pubmsg, &token);
    if (ret != MQTTCLIENT_SUCCESS) {
        printf("mqtt publish failed\r\n");
        return ret;
    }

    return ret;
}

/* 回调函数，处理消息到达 */
void delivered(void *context, MQTTClient_deliveryToken dt)
{
    unused(context);
    printf("Message with token value %d delivery confirmed\n", dt);

    deliveredToken = dt;
}

// 修改回调函数，处理接收到的控制命令
int messageArrived(void *context, char *topic_name, int topic_len, MQTTClient_message *message) {
    unused(context);
    unused(topic_len);

    printf("[Message recv topic]: %s\n", topic_name);
    char *payload = (char *)message->payload;
    printf("[Message]: %s\n", payload);
    printf("[Message over]\r\n");

    ControlState state;
    memset(&state, 0, sizeof(ControlState));
    
    // 解析控制消息
    parse_control_message(&state, payload);
    
    // 保存控制状态到结构体数组
    set_device_control_state(atoi(state.id), &state);
    // 打印控制状态
    print_control_state(&state);

    char output[128] = {0};
    build_message(&state, output, sizeof(output));

    uapi_uart_write(CONFIG_LORA_UART_BUS, (const uint8_t *)output, sizeof(output) + 1, 0);

    g_cmdFlag = 1;
    parse_after_equal(topic_name, g_response_id);
    MQTTClient_freeMessage(&message); // 正确释放消息
    MQTTClient_free(topic_name);     // 释放主题名称
    return 1;
}

void set_oled_iddata(int id){
            osal_printk("set_oled_iddata\r\n");

    unsigned char buff[64] = {0};  // 进一步扩大缓冲区
    int len = 0;
    if(device_exists[id]){
        len = sprintf((char*)buff, "data.n5.val=%d\xff\xff\xff",id);
        osal_printk("buff:%s\r\n",buff);
        if (oled_write(buff, len) != len) {
            osal_printk("Error sending id data\r\n");
        }
        send_to_oled_id = id;
    }else{
        len = sprintf((char*)buff, "id=0\xff\xff\xff");
        if (oled_write(buff, len) != len) {
            osal_printk("Error sending id data\r\n");
        }
        len = sprintf((char*)buff, "data.n5.val=0\xff\xff\xff");
        if (oled_write(buff, len) != len) {
            osal_printk("Error sending id data\r\n");
        }
        send_to_oled_id = 0;
    }
}
void lora_read_handler(const void *buffer, uint16_t length, bool error) {
    osal_kthread_lock();

    if (error || buffer == NULL || length == 0) {
        osal_printk("Invalid input: error=%d, buffer=%p, length=%u\n", error, buffer, length);
    osal_kthread_unlock();

        return;
    }

    const uint8_t *data = (const uint8_t *)buffer;

    // 防止缓冲区溢出
    if (uart_total_length + length >= sizeof(uart_total_buffer)) {
        osal_printk("Buffer overflow risk, resetting to keep recent data\n");
        // 尝试保留可能包含完整帧的尾部数据
        size_t keep_size = sizeof(uart_total_buffer) - length - 1;
        if (keep_size > 0 && uart_total_length > keep_size) {
            memmove(uart_total_buffer, uart_total_buffer + (uart_total_length - keep_size), keep_size);
            uart_total_length = keep_size;
        } else {
            uart_total_length = 0;
        }
    }

    // 追加新数据到缓冲区
    memcpy(uart_total_buffer + uart_total_length, data, length);
    uart_total_length += length;
    uart_total_buffer[uart_total_length] = '\0';

    // 调试：打印接收到的原始数据
    osal_printk("Raw buffer: %.*s\n", uart_total_length, uart_total_buffer);

    // 查找并处理所有完整的帧
    uint8_t *current_pos = uart_total_buffer;
    while (current_pos < uart_total_buffer + uart_total_length) {
        // 查找帧开始标记 "begin,"
        uint8_t *frame_start = (uint8_t*)strstr((char *)current_pos, "begin,");
        if (!frame_start) break;  // 没有更多完整帧
        
        // 查找帧结束标记 "over"
        uint8_t *frame_end = (uint8_t*)strstr((char *)frame_start, "over");
        if (!frame_end) break;    // 有开始但无结束，等待更多数据
        
        // 计算帧长度（从"begin,"到"over"之前）
        size_t frame_len = frame_end - frame_start;
        
        // 检查帧长度是否合理
        if (frame_len > 200) {  // 假设最大帧长度200字节
            osal_printk("Frame too long (%zu bytes), skipping\n", frame_len);
            current_pos = frame_end + 4;  // 跳过"over"
            continue;
        }
        
        // 提取完整帧
        char frame[256] = {0};
        size_t copy_len = frame_len < sizeof(frame) - 1 ? frame_len : sizeof(frame) - 1;
        memcpy(frame, frame_start, copy_len);
        frame[copy_len] = '\0';
        
        osal_printk("Processing frame: %s\n", frame);
        
        // 解析帧数据
        SensorData temp_data = {0};
        int parse_result = sscanf(
            frame, 
            "begin,%d,Hum:%[^,],Tem:%[^,],Lig:%[^,],SoilHum:%[^,],uv:%[^,],rain:%[^,],co2:%[^,]",
            &temp_data.id,
            temp_data.humidity,
            temp_data.temperature,
            temp_data.ligBuffer,
            temp_data.soilHum,
            temp_data.uv,
            temp_data.rain,
            temp_data.co2
        );
        
        // 验证解析结果
        if (parse_result != 8) {
            osal_printk("Parse failed! Expected 8 fields, got %d\n", parse_result);
            current_pos = frame_end + 4;  // 跳过"over"
            continue;
        }
        
        // 确保字符串安全终止
        #define SAFE_TERMINATE(str) str[sizeof(str) - 1] = '\0'
        SAFE_TERMINATE(temp_data.humidity);
        SAFE_TERMINATE(temp_data.temperature);
        SAFE_TERMINATE(temp_data.ligBuffer);
        SAFE_TERMINATE(temp_data.soilHum);
        SAFE_TERMINATE(temp_data.uv);
        SAFE_TERMINATE(temp_data.rain);
        SAFE_TERMINATE(temp_data.co2);
        
        // 打印并更新设备数据
        osal_printk("Parsed data for device %d:\n", temp_data.id);
        print_sensor_data(&temp_data);
        
        int idx = find_device_index(temp_data.id);
        if (idx >= 0) {
            // 只更新实际有值的字段
            update_device_data(&device_data[idx], &temp_data);
            send_flag = true;
            send_device_index = idx;
            osal_printk("Device %d updated\n", temp_data.id);
        } else {
            osal_printk("Device limit reached for ID %d\n", temp_data.id);
        }
        
        // 移动当前处理位置到帧结束之后
        current_pos = frame_end + 4;  // 跳过"over"
    }
    
    // 更新缓冲区：移走已处理的数据
    size_t remaining = uart_total_buffer + uart_total_length - current_pos;
    if (remaining > 0) {
        memmove(uart_total_buffer, current_pos, remaining);
        uart_total_length = remaining;
    } else {
        uart_total_length = 0;
    }
    uart_total_buffer[uart_total_length] = '\0';
    osal_kthread_unlock();

}


static errcode_t mqtt_connect(void)
{
    int ret;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    /* 初始化MQTT客户端 */
    MQTTClient_init();
    /* 创建 MQTT 客户端 */
    ret = MQTTClient_create(&client, SERVER_IP_ADDR, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if (ret != MQTTCLIENT_SUCCESS) {
        printf("Failed to create MQTT client, return code %d\n", ret);
        return ERRCODE_FAIL;
    }
    conn_opts.keepAliveInterval = KEEP_ALIVE_INTERVAL;
    conn_opts.cleansession = 1;
    conn_opts.username = g_username;
    conn_opts.password = g_password;
    // 绑定回调函数
    MQTTClient_setCallbacks(client, NULL, connlost, messageArrived, delivered);

    // 尝试连接
    if ((ret = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to connect, return code %d\n", ret);
        MQTTClient_destroy(&client); // 连接失败时销毁客户端
        return ERRCODE_FAIL;
    }
    printf("Connected to MQTT broker!\n");
    
    osDelay(DELAY_TIME_MS);
    // 订阅MQTT主题
    mqtt_subscribe(MQTT_CMDTOPIC_SUB);
    
    return ERRCODE_SUCC;
}

void main_task(const char *argument)
{
    unused(argument);


    // // oled串口初始化
    // oled_gpio_init();
    // oled_init_config();
    /* 等待wifi初始化完成 */
    while (wifi_is_wifi_inited() == 0) {
        (void)osDelay(10); /* 10: 延时100ms  */
    }
    /* 创建STA */
    if (wifi_sta_enable() != ERRCODE_SUCC) {
        PRINT("STA enbale fail !\r\n");
    }

    while (1) {
        osDelay(200);
        switch (centrl_state)
        {
        case UNKNOW :
        case CONNECTING : 
            centrl_state = CONNECTING;
            my_gpio_init(SENSOR_IO);
            wifi_connect();
            osDelay(DELAY_TIME_MS);
            
            if(mqtt_connect() == ERRCODE_SUCC){
                centrl_state = READY;

                oled_init();
                su_init();
                //Lora串口初始化
                uart_gpio_init(CONFIG_LORA_UART_BUS,CONFIG_LORA_TXD_PIN,CONFIG_LORA_RXD_PIN);
                // 对 UART 进行初始化配置
                uart_init_config(CONFIG_LORA_UART_BUS,CONFIG_LORA_TXD_PIN,CONFIG_LORA_RXD_PIN,&lora_buffer_config);
                uapi_uart_register_rx_callback(CONFIG_LORA_UART_BUS, UART_RX_CONDITION_MASK_IDLE, 1, lora_read_handler);
            }

            break;
        case READY :
            osal_printk("READY\r\n");
            //响应部分
            if (g_cmdFlag) {
                sprintf(g_send_buffer, MQTT_CLIENT_RESPONSE, g_response_id);
                // 设备响应命令
                if(mqtt_publish(g_send_buffer, g_response_buf) != MQTTCLIENT_SUCCESS){
                    MQTTClient_destroy(&client);
                    centrl_state=CONNECTING;//重新连接
                }
                g_cmdFlag = 0;
                memset(g_response_id, 0, sizeof(g_response_id) / sizeof(g_response_id[0]));

                // // 使用新函数发送指令并等待响应
                // if (send_command_and_wait_response(req, sizeof(req), 
                //                                   lora_recv, sizeof(lora_recv),
                //                                   10) > 0) { // 设置50次尝试
                //     // 复制响应数据到全局缓冲区
                //     // strncpy(g_response_buf, lora_recv, sizeof(g_response_buf) - 1);
                //     // 发布MQTT消息
                //     mqtt_publish(g_send_buffer, g_response_buf);
                // } else {
                //     osal_printk("Error: Failed to receive valid UART response\r\n");
                //     // 可以选择发送错误响应
                //     // mqtt_publish(g_send_buffer, "ERROR: Response timeout");
                // }
                // g_cmdFlag = 0;
                // memset(g_response_id, 0, sizeof(g_response_id));
            }
           
            if(send_flag && send_device_index >= 0)
            {
                //上报数据，使用设备索引获取对应数据
                memset(g_send_buffer, 0, sizeof(g_send_buffer) / sizeof(g_send_buffer[0]));
                sprintf(g_send_buffer, MQTT_DATA_SEND, DATA_SEVER_NAME,
                        device_data[send_device_index].id, "true",
                        device_data[send_device_index].humidity,
                        device_data[send_device_index].temperature,
                        device_data[send_device_index].ligBuffer,
                        device_data[send_device_index].soilHum,
                        device_data[send_device_index].rain,
                        device_data[send_device_index].uv,
                        device_data[send_device_index].co2);
                
                if(mqtt_publish(MQTT_DATATOPIC_PUB, g_send_buffer) != MQTTCLIENT_SUCCESS){
                    MQTTClient_destroy(&client);
                    centrl_state=CONNECTING;//重新连接
                }
                set_oled_data(&device_data[send_to_oled_id]);
                print_sensor_data(&device_data[send_to_oled_id]);

                // // 上报控制状态（可选）
                // ControlState control_state;
                    // if (get_device_control_state(atoi(device_data[send_device_index].id), &control_state)) {
                //     // 构建控制状态上报消息
                //     char control_msg[512] = {0};
                //     sprintf(control_msg, "{\"services\": [{\"service_id\": \"Control\",\"properties\": {"
                //                          "\"id\": %s,\"fan\": %s,\"water\": %s,\"sun\": %s,\"switch\": %s,"
                //                          "\"color_r\": %s,\"color_g\": %s,\"color_b\": %s}}]}",
                //                          control_state.id, control_state.fanFlag, control_state.waterFlag,
                //                          control_state.sunFlag, control_state.switchFlag,
                //                          control_state.colorNum[0], control_state.colorNum[1], control_state.colorNum[2]);
                    
                //     mqtt_publish(MQTT_CONTROLTOPIC_PUB, control_msg);
                // }

                send_flag=false;
                send_device_index = -1; // 重置设备索引
            }

            break;
        default:
            break;
        }
        // memset(g_send_buffer, 0, sizeof(g_send_buffer) / sizeof(g_send_buffer[0]));
    }
}

static void main_entry(void)
{
    osThreadAttr_t options;
    options.name = "main_task";
    options.attr_bits = 0;
    options.cb_mem = NULL;
    options.cb_size = 0;
    options.stack_mem = NULL;
    options.stack_size = 0x2000;
    options.priority = osPriorityNormal;

    main_task_id = osThreadNew((osThreadFunc_t)main_task, NULL, &options);
    if (main_task_id != NULL) {
        printf("ID = %d, Create main_task_id is OK!", main_task_id);
    }
}

/* Run the sample. */
app_run(main_entry);
